#pragma once

#include "data.h"



////////////////////////////////////////
// RawBuf.
////////////////////////////////////////
class RawBuf
{
public:
	inline s32_t Num() const
	{
		_check(mNum>=0);
		_check(mCap>=mNum);
		return mNum;
	}
	void Insert( s32_t index, s32_t cnt, s32_t eleSize )
	{
		_check(cnt>=0);
		_check(mNum>=0);
		_check(mCap>=mNum);
		_check(index>=0);
		_check(index<=mNum);

		s32_t oldNum = mNum;
		if( (mNum+=cnt)>mCap )
		{
			_resizeBuf( mCap + 3*mCap/8 + 32, eleSize );
		}
		coreMemmove( (u8_t*)mBuf + (index+cnt )*eleSize,
			(u8_t*)mBuf + (index)*eleSize, (oldNum-index)*eleSize );
	}
	s32_t Add( s32_t cnt, s32_t eleSize )
	{
		_check(cnt>=0);
		_check(mNum>=0);
		_check(mCap>=mNum);

		s32_t index = mNum;
		if( (mNum+=cnt)>mCap )
		{
			_resizeBuf( mCap + 3*mCap/8 + 32, eleSize );
		}

		return index;
	}
	void Shrink( s32_t eleSize )
	{
		_check(mNum>=0);
		_check(mCap>=mNum);
		if( mCap != mNum )
		{
			_resizeBuf( mNum, eleSize );
		}
	}
	void Clear( s32_t eleSize, s32_t save=0 )
	{
		mNum = 0;
		_resizeBuf( save, eleSize );
	}
	RawBuf()
		:mNum( 0)
		,mCap( 0)
		,mBuf( NULL)
	{}
	~RawBuf()
	{
		if( mBuf )
			coreFree( mBuf );
		mBuf = NULL;
		mNum = mCap = 0;
	}

	void RemoveAt( s32_t index, s32_t cnt, s32_t eleSize );

	s32_t BufCap()
	{
		return mCap;
	}
	void* Data()
	{
		return mBuf;
	}
protected:

	void _resizeBuf(  s32_t newSize ,s32_t eleSize );

	RawBuf( s32_t inNum, s32_t eleSize )
		:mNum( inNum )
		,mCap( 0)
		,mBuf( NULL)
	{
		_resizeBuf( inNum, eleSize );
	}
	void*	  mBuf;
	s32_t	  mNum;
	s32_t	  mCap;
};
